package com.gzhryc.common;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具
 * @author 张浩
 * @version 2017-2-13
 */
public class StringTools {
	
	static Pattern pat = Pattern.compile("^[+,-]?[0-9]+\\.?[0-9]*$");
	static Pattern pat1 = Pattern.compile("^[0-9]*$");
	static Pattern pat2 = Pattern.compile("^[A-Za-z0-9]+$");


	// 检查字符串是否包含中文或中文符号
	public static boolean isChinese(String strName) {
		char[] ch = strName.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			char c = ch[i];
			if (isChinese(c)) {
				return true;
			}
		}
		return false;
	}

	public static boolean isNumber(final String str) {
		if(StringUtils.isNotBlank(str) && pat.matcher(str).find()) {
			return true;
		}
		return false;
	}
	
	/**
	 * 是否是正整数
	 * @param str
	 * @return
	 */
	public static boolean isPositiveInteger(final String str) {
		if(StringUtils.isNotBlank(str) && pat1.matcher(str).find()) {
			return true;
		}
		return false;
	}
	
	// 根据Unicode编码完美的判断中文和符号
	private static boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
				|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
			return true;
		}
		return false;
	}

	/**
	 * 替换表情，如果数据库不支持保存表情符号时使用
	 * @param str
	 * @return
	 */
	public static String emojiFilter(String str){
		if(StringUtils.isNotBlank(str)){
			Pattern pat = Pattern.compile ("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
					Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
			Matcher mat = pat.matcher(str);
			while(mat.find()){
				str = mat.replaceFirst("");
				mat = pat.matcher(str);
			};
		}
		return str;
	}

	/**
	 * 将byte数组转换为表示16进制值的字符串， 如：byte[]{8,18}转换为：0813， 和public static byte[]
	 * hexStr2ByteArr(String strIn) 互为可逆的转换过程
	 * 
	 * @param arrB
	 *            需要转换的byte数组
	 * @return 转换后的字符串
	 */
	public static String byteArr2HexStr(byte[] arrB) {
		int iLen = arrB.length;
		// 每个byte用两个字符才能表示，所以字符串的长度是数组长度的两倍
		StringBuffer sb = new StringBuffer(iLen * 2);
		for (int i = 0; i < iLen; i++) {
			int intTmp = arrB[i];
			// 把负数转换为正数
			while (intTmp < 0) {
				intTmp = intTmp + 256;
			}
			// 小于0F的数需要在前面补0
			if (intTmp < 16) {
				sb.append("0");
			}
			sb.append(Integer.toString(intTmp, 16));
		}
		return sb.toString();
	}

	/**
	 * 将表示16进制值的字符串转换为byte数组， 和public static String byteArr2HexStr(byte[] arrB)
	 * 互为可逆的转换过程
	 * 
	 * @param strIn
	 *            需要转换的字符串
	 * @return 转换后的byte数组
	 * @throws NumberFormatException
	 */
	public static byte[] hexStr2ByteArr(String strIn) throws NumberFormatException {
		byte[] arrB = strIn.getBytes();
		int iLen = arrB.length;
		int cLen = arrB.length % 2;
		// 两个字符表示一个字节，所以字节数组长度是字符串长度除以2
		byte[] arrOut = new byte[(iLen / 2) + cLen];
		for (int i = 0; i < iLen; i = i + 2) {
			if(cLen == 1 && i == (iLen - cLen)){
				String strTmp = new String(arrB, i, cLen);
				arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
			}else {
				String strTmp = new String(arrB, i, 2);
				arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
			}
		}
		return arrOut;
	}
	
	public static List<Long> split2Long(String str,String regex){
		List<Long> result = null;
		if(StringUtils.isNotBlank(str)){
			String[] array = str.split(regex);
			result = new ArrayList<Long>(array.length);
			for(int i=0;i<array.length;i++){
				result.add(Long.valueOf(array[i]));
			}
		}
		return result;
	}

	public static String hexStringToString(String s) {
		if (s == null || s.equals("")) {
			return null;
		}
		s = s.replace(" ", "");
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "UTF-8");
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	public static String stringToAscii(String s){
		StringBuffer sbu = new StringBuffer();
		char[] chars = s.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			sbu.append((int)chars[i]);
		}
		return sbu.toString();
	}

	public static String stringToAsciiHex(String s) {
		StringBuffer sbu = new StringBuffer();
		char[] chars = s.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			sbu.append(Integer.toHexString((int)chars[i]));
		}
		return sbu.toString();
	}

	/**
	 * 避免StringUtils导入错误导致程序无法执行
	 * @param str
	 * @return
	 */
	public static boolean isNotBlank(String str){
		return StringUtils.isNotBlank(str);
	}

	public static boolean isBlank(String str){
		return StringUtils.isBlank(str);
	}
	
	/**
	 * 只包含数字和字母
	 * @param str
	 * @return
	 */
	public static boolean onlyNumberAndLetter(String str){
		if(str != null) {
			Matcher m = pat2.matcher(str);
			return m.matches();
		}
		return false;
	}


	/**
	 * 对路径中的中文进行URL编码
	 * @param str
	 * @param charset
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String urlChineseEncode(String str, String charset) throws UnsupportedEncodingException {
		Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
		Matcher m = p.matcher(str);
		StringBuffer b = new StringBuffer();
		while (m.find()) {
			m.appendReplacement(b, URLEncoder.encode(m.group(0), charset));
		}
		m.appendTail(b);
		return b.toString();
	}
}
